package com.imu.purse.modules.trade.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.github.pagehelper.PageHelper;
import com.imu.common.exception.ErrorDesc;
import com.imu.common.exception.RRException;
import com.imu.constant.Constant;
import com.imu.core.base.BaseService;
import com.imu.core.redisplus.annotation.RedisLock;
import com.imu.enums.OrderTypeStatus;
import com.imu.enums.PStatus;
import com.imu.enums.TradeType;
import com.imu.purse.modules.base.entity.SysConfigEntity;
import com.imu.purse.modules.trade.dao.PriequityMapper;
import com.imu.purse.modules.trade.entity.FundEntity;
import com.imu.purse.modules.trade.entity.PriequityEntity;
import com.imu.purse.modules.trade.entity.TradeInfoEntity;
import com.imu.purse.modules.trade.service.FundService;
import com.imu.purse.modules.trade.service.PriequityService;
import com.imu.purse.modules.trade.service.TradeInfoService;
import com.imu.utils.IDUtils;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.StrUtil;

/**
 * 私募明细
 * @author sunhongwei
 * @email sunhongwei@jshijian.com
 * @date 2018-03-22 10:33:20
 * Copyright (c) 2017 武汉极时间科技有限公司 版权所有 
 * Jshijian aloha CO.,LTD. All Rights Reserved. 
 */
@Service
public class PriequityServiceImpl extends BaseService<PriequityEntity> implements PriequityService 
{
	@Override
    @Transactional
    public int save(final PriequityEntity entity)
	{
		entity.setTimeCreate(new Date());
		entity.setTimeUpdate(new Date());
		entity.setState(PStatus.Create.getType());
    	return super.insert(entity);
	}
	
	@Override
	@Transactional
    public int update(final PriequityEntity tradeInfo) 
    {
    	return mapper.updateByPrimaryKeySelective(tradeInfo);
    }
    
    @Override
	@Transactional
    public int saveUpdate(final PriequityEntity tradeInfo)
    {
    	int len = 0;
    	
    	if(1 > (len = this.update(tradeInfo)))
    	{
        	len = this.insert(tradeInfo);
    	}
    	
    	return len;
    }
    
 	@Override
	@Transactional
    public boolean delete(final String ...ids)
    {
    	if(ArrayUtil.isEmpty(ids)) return false;
    	
    	for (String id : ids) 
    	{
    		if(StrUtil.isBlank(id)) continue;
    		
    		if(NumberUtil.isNumber(id))
    		{
        		mapper.deleteByPrimaryKey(Long.valueOf(id));
    		}
		}
    	
    	return true;
    }
 	
 	@Override
	@Transactional
	@RedisLock(keys = "#key", expire = 30000, tryTimeout = 1000)
 	public BigDecimal priMoney(final String key, final PriequityEntity dto)
 	{
 		//验证用户余额信息 是否支持本次私募
        FundEntity fund = fundService.findByUserId(dto.getUserId());
        if(null == fund) {
        	throw new RRException(ErrorDesc.GET_USER_ERR.getMsg(), ErrorDesc.GET_USER_ERR.getCode());
        }
        else if(null == fund.getBj() || fund.getBj().compareTo(dto.getPayBj()) < 0) {
        	throw new RRException(ErrorDesc.YMB_LESS_THAN.getMsg(), ErrorDesc.YMB_LESS_THAN.getCode());
        }
        else if(null == fund.getMoney() || fund.getMoney().compareTo(dto.getPayImu()) < 0) {
        	throw new RRException(ErrorDesc.IMU_LESS_THAN.getMsg(), ErrorDesc.IMU_LESS_THAN.getCode());
        }
 		//查看是否允许本次私募
        BigDecimal count = new BigDecimal(0l);
        SysConfigEntity config = sysConfigService.findByKey(Constant.CFG_COWRY_COUNT_KEY);
        if(null != config && StrUtil.isNotBlank(config.getValue())) {
        	count = new BigDecimal(config.getValue());
        }
        
        //判断用户输入值是否大于可用贝壳数
        if(null == config || count.longValue() < 1 ||  dto.getBuyNum().compareTo(count) > 0) {
        	throw new RRException(ErrorDesc.PRIEQUITY_THAN.getMsg(), ErrorDesc.PRIEQUITY_THAN.getCode());
        }
        
        //判断用户私募数量
        if(null == verify || verify.booleanValue())
        {
        	count = mapper.sumBuyNum(dto.getUserId(), 0);
	        if(null != count && 500 < (count.doubleValue() + dto.getBuyNum().doubleValue())) {
	        	throw new RRException(ErrorDesc.PRI_QUANTUM.getMsg(), ErrorDesc.PRI_QUANTUM.getCode());
	        }
        }
        //私募信息归集
        config = sysConfigService.findByKey(Constant.PRI_USER_KEY);
        Long userId = 0l;
        if(null != config && StrUtil.isNotBlank(config.getValue()))
        {
        	try {
				userId = Long.valueOf(config.getValue());
        	} 
        	catch (Exception e) { }
        }
        //保存私募信息
        this.save(dto);
        
        //扣减IMU 保存流水记录
        String oid = IDUtils.getOrder();
        TradeInfoEntity tradeEntity = new TradeInfoEntity();
        tradeEntity.setId(null);
        tradeEntity.setOrderNo(oid);
        tradeEntity.setPayUserId(dto.getUserId());
        tradeEntity.setRecUserId(userId);
        tradeEntity.setMoney(dto.getPayImu());
        tradeEntity.setSmoney(fund.getMoney());
        tradeEntity.setEmoney(fund.getMoney().subtract(dto.getPayImu()));
        tradeEntity.setOrderType(OrderTypeStatus.OUT.getType());
        tradeEntity.setOrderState(PStatus.Finished.getType());
        tradeEntity.setYtfType(TradeType.IMU.getType());
        tradeInfoService.save(tradeEntity);
        //扣减IMU
        FundEntity fundEntity = new FundEntity();
        fundEntity.setUserId(dto.getUserId());
        fundEntity.setMoney(dto.getPayImu().multiply(new BigDecimal(-1)));
        fundEntity.setYtfType(TradeType.IMU.getType());
        fundService.updateMoneyByUIdAndYtype(fundEntity);
        
        //扣减易买宝 保存流水记录
        tradeEntity.setId(null);
        tradeEntity.setMoney(dto.getPayBj());
        tradeEntity.setSmoney(fund.getBj());
        tradeEntity.setEmoney(fund.getBj().subtract(dto.getPayBj()));
        tradeEntity.setYtfType(TradeType.YMB.getType());
        tradeInfoService.save(tradeEntity);

        fundEntity.setMoney(dto.getPayBj().multiply(new BigDecimal(-1)));
        fundEntity.setYtfType(TradeType.YMB.getType());
        fundService.updateMoneyByUIdAndYtype(fundEntity);
        
        //更新私募贝壳数
        BigDecimal num = sysConfigService.priGrab(dto.getBuyNum());
        //增加贝壳数  保存流水记录
        tradeEntity.setId(null);
        tradeEntity.setMoney(dto.getBuyNum());
        tradeEntity.setRecUserId(dto.getUserId());
        tradeEntity.setSmoney(fund.getLockcowry());
        tradeEntity.setEmoney(fund.getLockcowry().add(dto.getBuyNum()));
        tradeEntity.setOrderNo(String.valueOf(dto.getId()));
        tradeEntity.setYtfType(TradeType.COWRY.getType());
        tradeEntity.setOrderType(OrderTypeStatus.PRIEQUITY.getType());
        tradeInfoService.save(tradeEntity);

        fundEntity.setMoney(dto.getBuyNum());
        fundEntity.setYtfType(TradeType.COWRY.getType());
        fundService.updateMoneyByUIdAndYtype(fundEntity);
        
        //私募信息归集
        if(userId > 0) {
        	fund = fundService.findByUserId(userId);
        	
        	if(null != fund)
        	{
    			//增加IMU 买宝 保存流水记录
    	        tradeEntity.setId(null);
    	        tradeEntity.setOrderNo(oid);
    	        tradeEntity.setPayUserId(userId);
    	        tradeEntity.setRecUserId(dto.getUserId());
    	        tradeEntity.setMoney(dto.getPayImu());
    	        tradeEntity.setSmoney(fund.getMoney());
    	        tradeEntity.setEmoney(fund.getMoney().add(dto.getPayImu()));
    	        tradeEntity.setOrderType(OrderTypeStatus.IN.getType());
    	        tradeEntity.setYtfType(TradeType.IMU.getType());
    	        tradeInfoService.save(tradeEntity);
    			
    	        tradeEntity.setId(null);
    	        tradeEntity.setPayUserId(userId);
    	        tradeEntity.setRecUserId(dto.getUserId());
    	        tradeEntity.setMoney(dto.getPayBj());
    	        tradeEntity.setSmoney(fund.getBj());
    	        tradeEntity.setEmoney(fund.getBj().add(dto.getPayBj()));
    	        tradeEntity.setOrderType(OrderTypeStatus.IN.getType());
    	        tradeEntity.setYtfType(TradeType.YMB.getType());
    	        tradeInfoService.save(tradeEntity);
    	        
    			fundEntity.setUserId(userId.longValue());
    			fundEntity.setMoney(dto.getPayImu());
    			fundEntity.setBj(dto.getPayBj());
    			fundService.up(fundEntity);
        	}
        }
        
        return num;
 	}
 	
 	@Override
	@Transactional
	@RedisLock(keys = "#key", expire = 30000, tryTimeout = 1000)
 	public BigDecimal priGet(final String key, final PriequityEntity dto)
 	{
 		//验证用户余额信息 是否支持本次私募
        FundEntity fund = fundService.findByUserId(dto.getUserId());
        if(null == fund) {
        	throw new RRException(ErrorDesc.GET_USER_ERR.getMsg(), ErrorDesc.GET_USER_ERR.getCode());
        }
        else if(null == fund.getBj() || fund.getBj().compareTo(dto.getPayBj()) < 0) {
        	throw new RRException(ErrorDesc.YMB_LESS_THAN.getMsg(), ErrorDesc.YMB_LESS_THAN.getCode());
        }
        else if(null == fund.getLocketh() || fund.getLocketh().compareTo(dto.getPayGet()) < 0) {
        	throw new RRException(ErrorDesc.GET_LESS_THAN.getMsg(), ErrorDesc.GET_LESS_THAN.getCode());
        }
        
 		//查看是否允许本次私募
        BigDecimal count = new BigDecimal(0l);
        SysConfigEntity config = sysConfigService.findByKey(Constant.CFG_COWRY_COUNT_KEY);
        if(null != config && StrUtil.isNotBlank(config.getValue())) {
        	count = new BigDecimal(config.getValue());
        }
        
        //判断用户输入值是否大于可用贝壳数
        if(null == config || count.longValue() < 1 || dto.getBuyNum().compareTo(count) > 0) {
        	throw new RRException(ErrorDesc.PRIEQUITY_THAN.getMsg(), ErrorDesc.PRIEQUITY_THAN.getCode());
        }
        
        //判断用户私募数量
        if(null == verify || verify.booleanValue())
        {
        	count = mapper.sumBuyNum(dto.getUserId(), 1);
	        if(null != count && 2500 < (count.doubleValue() + dto.getBuyNum().doubleValue())) {
	        	throw new RRException(String.format(ErrorDesc.BK_QUANTUM_2500.getMsg(), count.longValue()), ErrorDesc.BK_QUANTUM_2500.getCode());
	        }
        }
        //私募信息归集
        config = sysConfigService.findByKey(Constant.PRI_USER_KEY);
        Long userId = 0l;
        if(null != config && StrUtil.isNotBlank(config.getValue()))
        {
        	try {
				userId = Long.valueOf(config.getValue());
        	} 
        	catch (Exception e) { }
        }
        //保存私募信息
        this.save(dto);
        
        //扣减GET 保存流水记录
        String oid = IDUtils.getOrder();
        TradeInfoEntity tradeEntity = new TradeInfoEntity();
        tradeEntity.setId(null);
        tradeEntity.setOrderNo(oid);
        tradeEntity.setPayUserId(dto.getUserId());
        tradeEntity.setRecUserId(userId);
        tradeEntity.setMoney(dto.getPayGet());
        tradeEntity.setSmoney(fund.getLocketh());
        tradeEntity.setEmoney(fund.getLocketh().subtract(dto.getPayGet()));
        tradeEntity.setOrderState(PStatus.Finished.getType());
        tradeEntity.setYtfType(TradeType.GET.getType());
        tradeEntity.setOrderType(OrderTypeStatus.OUT.getType());
        tradeInfoService.save(tradeEntity);
        
        //扣减易买宝 保存流水记录
        tradeEntity.setId(null);
        tradeEntity.setMoney(dto.getPayBj());
        tradeEntity.setSmoney(fund.getBj());
        tradeEntity.setEmoney(fund.getBj().subtract(dto.getPayBj()));
        tradeEntity.setYtfType(TradeType.YMB.getType());
        tradeInfoService.save(tradeEntity);
        
        //更新私募贝壳数
        BigDecimal num = sysConfigService.priGrab(dto.getBuyNum());
        //增加贝壳数  保存流水记录
        tradeEntity.setId(null);
        tradeEntity.setMoney(dto.getBuyNum());
        tradeEntity.setRecUserId(dto.getUserId());
        tradeEntity.setSmoney(fund.getLockcowry());
        tradeEntity.setOrderNo(String.valueOf(dto.getId()));
        tradeEntity.setEmoney(fund.getLockcowry().add(dto.getBuyNum()));
        tradeEntity.setYtfType(TradeType.COWRY.getType());
        tradeEntity.setOrderType(OrderTypeStatus.PRIEQUITY.getType());
        tradeInfoService.save(tradeEntity);

        //扣减YMB, GET, 贝壳
        FundEntity fundEntity = new FundEntity();
        fundEntity.setUserId(dto.getUserId());
        fundEntity.setLockcowry(dto.getBuyNum());
        fundEntity.setBj(dto.getPayBj().multiply(new BigDecimal(-1)));
        fundEntity.setLocketh(dto.getPayGet().multiply(new BigDecimal(-1)));
        fundService.upPri(fundEntity);
        
        //私募信息归集
        if(userId > 0) {
        	fund = fundService.findByUserId(userId);
        	
        	if(null != fund)
        	{
        		//增加GET 保存流水记录
    	        tradeEntity.setId(null);
    	        tradeEntity.setOrderNo(oid);
    	        tradeEntity.setPayUserId(userId);
    	        tradeEntity.setRecUserId(dto.getUserId());
    	        tradeEntity.setMoney(dto.getPayGet());
    	        tradeEntity.setSmoney(fund.getLocketh());
    	        tradeEntity.setEmoney(fund.getLocketh().add(dto.getPayGet()));
    	        tradeEntity.setOrderType(OrderTypeStatus.IN.getType());
    	        tradeEntity.setYtfType(TradeType.GET.getType());
    	        tradeInfoService.save(tradeEntity);
    	        //增加易买宝 保存流水记录
    	        tradeEntity.setId(null);
    	        tradeEntity.setPayUserId(userId);
    	        tradeEntity.setRecUserId(dto.getUserId());
    	        tradeEntity.setMoney(dto.getPayBj());
    	        tradeEntity.setSmoney(fund.getBj());
    	        tradeEntity.setEmoney(fund.getBj().add(dto.getPayBj()));
    	        tradeEntity.setOrderType(OrderTypeStatus.IN.getType());
    	        tradeEntity.setYtfType(TradeType.YMB.getType());
    	        tradeInfoService.save(tradeEntity);
    	        
    	        fundEntity = new FundEntity();
    			fundEntity.setUserId(userId.longValue());
    			fundEntity.setLocketh(dto.getPayGet());
    			fundEntity.setBj(dto.getPayBj());
    			fundService.up(fundEntity);
        	}
        }
        
        return num;
 	}
    
    @Override
    public PriequityEntity findById(final Long id)
    {
    	if(null == id) return null;
    	return mapper.selectByPrimaryKey(id);
    }
    
    @Override
    public List<PriequityEntity> queryList(final PriequityEntity tradeInfo)
    {
    	if (tradeInfo.getPage() != null && tradeInfo.getLimit() != null)
    	{
            PageHelper.startPage(tradeInfo.getPage(), tradeInfo.getLimit());
        }
    	
    	return mapper.findByPage(tradeInfo);
    }
    /****
     *是否验证签名
     */
    @Value("${app.priequity.verify}")
    private Boolean verify;
    
	@Autowired
	private PriequityMapper mapper;
	
	@Autowired
	private FundService fundService;
	
	@Autowired
	private TradeInfoService tradeInfoService;

    @Autowired
    private com.imu.purse.modules.base.service.SysConfigService sysConfigService;
}
